package com.smasher.domain.room

import android.util.Log
import androidx.room.Room.databaseBuilder
import androidx.room.RoomDatabase.Callback
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.smasher.core.other.ApplicationContext

object DBManager {

    private const val TAG: String = "LoongDatabase"
    private const val DATABASE_NAME = "domain.db"

    private val mCallback: Callback = object : Callback() {
        override fun onCreate(db: SupportSQLiteDatabase) {
            super.onCreate(db)
            Log.d(TAG, "onCreate: ")
            //在新装app时会调用，调用时机为数据库build()之后，数据库升级时不调用此函数
            MIGRATIONS.map {
                it.migrate(db)
            }
        }

        override fun onOpen(db: SupportSQLiteDatabase) {
            super.onOpen(db)
            Log.d(TAG, "onOpen: ")
        }

        override fun onDestructiveMigration(db: SupportSQLiteDatabase) {
            super.onDestructiveMigration(db)
            Log.d(TAG, "onDestructiveMigration: ")
        }
    }

    /**
     * 数据库变动添加Migration
     */
    private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
        override fun migrate(db: SupportSQLiteDatabase) {
            // 在Android SQLite中，直接使用 ALTER TABLE ... ALTER COLUMN ... 语法来修改列的约束是不支持的。
            // 需要通过创建一个新表、复制数据、删除旧表并重命名新表的方式来实现。
            // 创建临时表
            db.execSQL("CREATE TABLE domains_temp (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, scheme TEXT NOT NULL, host TEXT NOT NULL, port INTEGER NOT NULL)")
            // 复制数据
            db.execSQL("INSERT INTO domains_temp (id, name, scheme, host, port) SELECT id, name, scheme, host, port FROM domains")
            // 删除旧表
            db.execSQL("DROP TABLE domains")
            // 重命名临时表
            db.execSQL("ALTER TABLE domains_temp RENAME TO domains")
        }
    }

    private val MIGRATION_9_10: Migration = object : Migration(9, 10) {
        override fun migrate(db: SupportSQLiteDatabase) {
            db.execSQL("CREATE TABLE IF NOT EXISTS `navigation` (`compositeId` TEXT NOT NULL, `mainId` TEXT NOT NULL, `name` TEXT NOT NULL, `navId` TEXT NOT NULL, `userId` TEXT NOT NULL, PRIMARY KEY(`compositeId`))")
            db.execSQL("CREATE TABLE IF NOT EXISTS `alpaca` (`compositeId` TEXT NOT NULL, `id` TEXT NOT NULL, `name` TEXT NOT NULL, `navId` TEXT NOT NULL, `navScrollId` TEXT NOT NULL, `userId` TEXT NOT NULL, PRIMARY KEY(`compositeId`), FOREIGN KEY(`compositeId`) REFERENCES `navigation`(`compositeId`) ON UPDATE CASCADE ON DELETE CASCADE )")
            db.execSQL("CREATE TABLE IF NOT EXISTS `bear` (`compositeId` TEXT NOT NULL, `compositeGroup` TEXT NOT NULL, `iconClass` TEXT, `id` TEXT, `img` TEXT, `name` TEXT NOT NULL, `path` TEXT NOT NULL, `navId` TEXT NOT NULL, `userId` TEXT NOT NULL, PRIMARY KEY(`compositeId`), FOREIGN KEY(`compositeGroup`) REFERENCES `alpaca`(`compositeId`) ON UPDATE CASCADE ON DELETE CASCADE )")
            db.execSQL("CREATE TABLE IF NOT EXISTS `permission` (`permission` TEXT NOT NULL, `userId` TEXT NOT NULL, PRIMARY KEY(`permission`))")
            db.execSQL("CREATE TABLE IF NOT EXISTS `industry` (`Id` TEXT NOT NULL, `BaseId` TEXT NOT NULL, `Code` TEXT, `CreateTime` TEXT NOT NULL, `CreatorId` TEXT NOT NULL, `Deleted` INTEGER NOT NULL, `Description` TEXT, `IsEnable` INTEGER NOT NULL, `Name` TEXT NOT NULL, `SortCode` INTEGER NOT NULL, `SystemMark` INTEGER NOT NULL, `Type` INTEGER NOT NULL, `Value` TEXT NOT NULL, PRIMARY KEY(`Id`))")
        }
    }

    private val MIGRATIONS = arrayOf(MIGRATION_1_2)

    val db: AppDataBase by lazy {
        databaseBuilder(
            ApplicationContext.getInstance(), AppDataBase::class.java, DATABASE_NAME
        )//添加数据库变动迁移
            .addMigrations(*MIGRATIONS)
            .fallbackToDestructiveMigration()
            .addCallback(mCallback).build()
    }


}